/* 
 * File:   Texture.cpp
 * Author: agu
 * 
 * Created on 22 de mayo de 2014, 15:34
 */

#include <SDL2/SDL_image.h>

#include "Texture.h"
#include "InitializationException.h"
#include <iostream>

Texture::Texture() {
    this->texture = NULL;
}

Texture::Texture(SDL_Renderer* renderer, const string path, int x, int y) {
    SDL_Surface* loadedSurface = IMG_Load(path.c_str());
    if (loadedSurface == NULL)
        throw InitializationException(IMG_GetError());
    this->renderer = renderer;
    //Ver esto
    SDL_SetColorKey(loadedSurface, SDL_TRUE, SDL_MapRGB(loadedSurface->format, 0xFF, 0xFF, 0xFF));
    this->texture = SDL_CreateTextureFromSurface(this->renderer, loadedSurface);

    if (this->texture != NULL) {
        //Get image dimensions
        std::cout << path << std::endl;
        std::cout << "(" << loadedSurface->w << "," << loadedSurface->h << ")" << std::endl;
        this->position.w = loadedSurface->w;
        this->position.h = loadedSurface->h;
    } else {
        //Mejorar esto
        std::cout << SDL_GetError() << std::endl;
    }
    this->position.x = x;
    this->position.y = y;
    //Get rid of old loaded surface
    SDL_FreeSurface(loadedSurface);
}

Texture::Texture(SDL_Renderer* renderer, const string path) {
    this->renderer = renderer;
    Surface surface(path.c_str());
    this->texture = SDL_CreateTextureFromSurface(renderer, surface.getSurfaceSDL());
    if (texture == NULL)
        throw InitializationException(SDL_GetError());
}

Texture::Texture(SDL_Renderer* renderer, int x, int y) {
    this->renderer = renderer;
    this->position.x = x;
    this->position.y = y;
    this->texture = NULL;
}

Texture::~Texture() {
    if (this->texture != NULL) {
        SDL_DestroyTexture(this->texture);
        this->texture = NULL;
    }
}

SDL_Texture* Texture::getTextureSDL() {
    return this->texture;
}

int Texture::getWidth() {
    return this->position.w;
}

int Texture::getHeight() {
    return this->position.h;
}

int Texture::getX() {
    return this->position.x;
}

int Texture::getY() {
    return this->position.y;
}

void Texture::setColor(Uint8 red, Uint8 green, Uint8 blue) {
    //Modulate texture rgb
    SDL_SetTextureColorMod(this->texture, red, green, blue);
}

void Texture::setBlendMode(SDL_BlendMode blending) {
    //Set blending function
    SDL_SetTextureBlendMode(this->texture, blending);
}

void Texture::setAlpha(Uint8 alpha) {
    //Modulate texture alpha
    SDL_SetTextureAlphaMod(this->texture, alpha);
}

void Texture::render() {

    //Este es para dibujar una imagen que no va a cambiar
    SDL_Rect renderQuad = {this->position.x, this->position.y,
        this->position.w, this->position.h};
    //Render to screen

    int err = SDL_RenderCopy(this->renderer, this->texture,
            NULL, &renderQuad);
    if (err < 0) {
        std::cout << SDL_GetError() << std::endl;
    }
}

void Texture::render(SDL_Rect* clip) {
    SDL_Rect renderQuad = {this->position.x, this->position.y,
        this->position.w, this->position.h};
    //Render to screen
    SDL_RenderCopy(this->renderer, this->texture, clip, &renderQuad);
}

void Texture::render(int x, int y, SDL_Rect* clip) {
    //Set rendering space and render to screen
    SDL_Rect renderQuad = {x, y, this->position.w, this->position.h};
    //Set clip rendering dimensions
    if (clip != NULL) {
        renderQuad.w = clip->w;
        renderQuad.h = clip->h;
    }
    //Render to screen
    SDL_RenderCopy(this->renderer, this->texture, clip, &renderQuad);
}

void Texture::render(int x, int y, int width, int height, SDL_Rect* clip) {
    //Set rendering space and render to screen
    SDL_Rect renderQuad = {x, y, width, height};
    //Render to screen
    SDL_RenderCopy(this->renderer, this->texture, clip, &renderQuad);

}
void Texture::render(int x, int y, int width, int height) {
    //Set rendering space and render to screen
    SDL_Rect renderQuad = {x, y, width, height};
    //Render to screen
    SDL_RenderCopy(this->renderer, this->texture, NULL, &renderQuad);

}
void Texture::render(int x, int y, SDL_Rect* clip, double angle,
        SDL_Point* center, SDL_RendererFlip flip) {
    //Set rendering space and render to screen
    SDL_Rect renderQuad = {x, y, this->position.w, this->position.h};

    //Set clip rendering dimensions
    if (clip != NULL) {
        renderQuad.w = clip->w;
        renderQuad.h = clip->h;
    }

    //Render to screen
    SDL_RenderCopyEx(this->renderer, this->texture, clip, &renderQuad, angle,
            center, flip);

}

void Texture::resize(int width, int height) {
    this->position.w = width;
    this->position.h = height;
}

void Texture::setPosition(int x, int y) {
    this->position.x = x;
    this->position.y = y;
}

void Texture::load(Surface& surface) {
    if (this->texture != NULL)
        SDL_DestroyTexture(this->texture);
    this->texture = SDL_CreateTextureFromSurface(this->renderer, surface.getSurfaceSDL());
    this->resize(surface.getWidth(), surface.getheight());
}

void Texture::setRender(SDL_Renderer* renderer) {
    this->renderer = renderer;
}